/**
@file
Contains ToString functions.

Version:
0.1.0

Last updated date:
2012-12-04

Created date:
2012-08-15
*/


#pragma once
#include <string>
#include "CString.h"


namespace Zaf {
namespace String {
namespace __Internal {



#define __Zaf_ToString_Call_Long_N2S__(type, value, radix, size, buffer)            \
if (radix == 10) {                                                                  \
	__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);                \
}                                                                                   \
else {                                                                              \
	__N2SWrapper<CharType, long>::__N2S((unsigned type)value, radix, size, buffer); \
}



//Declaration
template<typename CharType, typename ValueType>
struct __N2SWrapper {
	static void __N2S(ValueType value, int radix, int size, CharType* buffer);
};



//long
template<typename CharType>
struct __N2SWrapper<CharType, long> {
	static void __N2S(long value, int radix, int size, CharType* buffer) {
		LongToStr(value, buffer, size, radix);
	}
};

//unsigned long
template<typename CharType>
struct __N2SWrapper<CharType, unsigned long> {
	static void __N2S(unsigned long value, int radix, int size, CharType* buffer) {
		ULongToStr(value, buffer, size, radix);
	}
};



//long long
template<typename CharType>
struct __N2SWrapper<CharType, long long> {
	static void __N2S(long long value, int radix, int size, CharType* buffer) {
		LLongToStr(value, buffer, size, radix);
	}
};

//unsigned long long
template<typename CharType>
struct __N2SWrapper<CharType, unsigned long long> {
	static void __N2S(unsigned long long value, int radix, int size, CharType* buffer) {
		ULLongToStr(value, buffer, size, radix);
	}
};



//char
template<typename CharType>
struct __N2SWrapper<CharType, char> {
	static void __N2S(char value, int radix, int size, CharType* buffer) {
		__Zaf_ToString_Call_Long_N2S__(char, value, radix, size, buffer);
	}
};

//signed char
template<typename CharType>
struct __N2SWrapper<CharType, signed char> {
	static void __N2S(signed char value, int radix, int size, CharType* buffer) {
		__Zaf_ToString_Call_Long_N2S__(char, value, radix, size, buffer);
	}
};

//unsigned char
template<typename CharType>
struct __N2SWrapper<CharType, unsigned char> {
	static void __N2S(unsigned char value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};



//wchar_t
template<typename CharType>
struct __N2SWrapper<CharType, wchar_t> {
	static void __N2S(wchar_t value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};



//short
template<typename CharType>
struct __N2SWrapper<CharType, short> {
	static void __N2S(short value, int radix, int size, CharType* buffer) {
		__Zaf_ToString_Call_Long_N2S__(short, value, radix, size, buffer);
	}
};

//unsigned short
template<typename CharType>
struct __N2SWrapper<CharType, unsigned short> {
	static void __N2S(unsigned short value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};



//int
template<typename CharType>
struct __N2SWrapper<CharType, int> {
	static void __N2S(int value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, long>::__N2S(value, radix, size, buffer);
	}
};

//unsigned int
template<typename CharType>
struct __N2SWrapper<CharType, unsigned int> {
	static void __N2S(unsigned int value, int radix, int size, CharType* buffer) {
		__N2SWrapper<CharType, unsigned long>::__N2S(value, radix, size, buffer);
	}
};



} // __Internal



#define __Zaf_ToString_DefaultRadix__ (10)
#define __Zaf_ToString_MaxNumberDigits__ (64)



/**
Converts an integer value to string.

@param value Integer value to be converted.
@param radix The radix of number to be used, default to 10.
@return %String represents the integer value.

The available type of \a value is included in the list below:
- char
- signed char
- unsigned char
- wchar_t
- short
- unsigned short
- int
- unsigned int
- long
- unsigned long
- long long
- unsigned long long

For those \a value whose type is char, signed char, unsigned char 
or wchar_t, this function converts their numeric value other than
character value to string. For example, ToString('0') would get
string "48".

\a radix must be in range 2 - 36, or it would cause undefined 
behavior.
*/
template<typename CharType, typename ValueType>
inline std::basic_string<CharType> ToString(ValueType value, int radix = __Zaf_ToString_DefaultRadix__) {

	CharType buffer[__Zaf_ToString_MaxNumberDigits__ + 1];

	__Internal::__N2SWrapper<CharType, ValueType>::__N2S(
		value, 
		radix, 
		__Zaf_ToString_MaxNumberDigits__ + 1, 
		buffer
	); 

	return buffer;
}


} 
}